// 判断是否为联合类型
// 条件类型中如果左边的类型是联合类型，
// 会把每个元素单独传入做计算，而右边不会
// A extends A 这段看似没啥意义，
// 主要是为了触发分布式条件类型，让 A 的每个类型单独传入

// A extends A 这种写法是为了触发分布式条件类型，让每个类型单独传入处理的，没别的意义。
// A extends A 和 [A] extends [A] 是不同的处理，前者是单个类型和整个类型做判断，后者两边都是整个联合类型，
// 因为只有 extends 左边直接是类型参数才会触发分布式条件类型
type IsUnion<A, B = A> = A extends A
? [B] extends [A]
  ? false
  : true
: never

// 数组转联合类型
type union = ['aaa', 'bbb'][number]

// bem 是 css 命名规范，
// 用 block__element--modifier 的形式来描述某个区块下面的某个元素的某个状态的样式。
type BEM<
    Block extends string,
    Element extends string[],
    Modifiers extends string[]
> = `${Block}__${Element[number]}--${Modifiers[number]}`;
type BEMRes = BEM<'xie', ['aaa', 'bbb'], ['yes', 'no']>

/// 联合类型两两组合
type AllCombinations<A extends string, B extends string = A> = 
A extends A
? Combination<A, AllCombinations<Exclude<B, A>>>
: never;

type Combination<A extends string, B extends string> =
| A
| B
| `${A}${B}`
| `${B}${A}`;

// never代表没有
// never和其他的值合并都为never 那么没有就被舍弃了
// 所以就只有'a'了
type CombinationRes = Combination<'a', never>

type AllCombinationsRes = AllCombinations<'a' | 'b' | 'c'>